package tum0r.image;

import java.awt.*;
import java.awt.image.BufferedImage;

/**
 * 获取图片的递度图，即颜色在X方向和Y方向上的变化边界图、
 * <p>
 * ClassName: Gradient
 * Author: tum0r
 * Time: 2020/4/11 13:12
 */
public class Gradient extends ImageBase {

    // 表示X方向和Y方向的递度
    private boolean X = true;
    private boolean Y = true;

    public Gradient() {
    }

    public Gradient(boolean X, boolean Y) {
        this.X = X;
        this.Y = Y;
    }

    /**
     * 处理图片，获取递度图，当颜色在X或Y方向上有变化时会保留下来，没有变化则为黑色【RGB(0, 0, 0)】
     *
     * @param image 要处理的图片BufferedImage对象
     * @return 递度图的BufferedImage对象
     */
    @Override
    public BufferedImage handle(BufferedImage image) {
        BufferedImage result = null;
        if (image != null) {
            int width = image.getWidth();
            int height = image.getHeight();
            result = new BufferedImage(width, height, image.getType());
            width--;
            height--;

            int ARGB;
            int[] ARGB_X = new int[4];
            int[] ARGB_Y = new int[4];
            int alpha;
            int red;
            int green;
            int blue;

            for (int x = 0; x < width; x++) {
                for (int y = 0; y < height; y++) {
                    ARGB = image.getRGB(x, y);
                    ARGB_X[0] = image.getRGB(x + 1, y);
                    ARGB_Y[0] = image.getRGB(x, y + 1);
                    alpha = (ARGB >> 24) & 0xff;

                    ARGB_X[1] = ((ARGB >> 16) & 0xff) - ((ARGB_X[0] >> 16) & 0xff);
                    ARGB_X[2] = ((ARGB >> 8) & 0xff) - ((ARGB_X[0] >> 8) & 0xff);
                    ARGB_X[3] = (ARGB & 0xff) - (ARGB_X[0] & 0xff);

                    ARGB_Y[1] = ((ARGB >> 16) & 0xff) - ((ARGB_Y[0] >> 16) & 0xff);
                    ARGB_Y[2] = ((ARGB >> 8) & 0xff) - ((ARGB_Y[0] >> 8) & 0xff);
                    ARGB_Y[3] = (ARGB & 0xff) - (ARGB_Y[0] & 0xff);

                    if (X && Y) {
                        red = (int) (Math.sqrt(Math.pow(ARGB_X[1], 2) + Math.pow(ARGB_Y[1], 2)) + 0.5);
                        green = (int) (Math.sqrt(Math.pow(ARGB_X[2], 2) + Math.pow(ARGB_Y[2], 2)) + 0.5);
                        blue = (int) (Math.sqrt(Math.pow(ARGB_X[3], 2) + Math.pow(ARGB_Y[3], 2)) + 0.5);
                    } else if (X) {
                        red = ARGB_X[1];
                        green = ARGB_X[2];
                        blue = ARGB_X[3];
                    } else if (Y) {
                        red = ARGB_Y[1];
                        green = ARGB_Y[2];
                        blue = ARGB_Y[3];
                    } else {
                        red = 0;
                        green = 0;
                        blue = 0;
                    }
                    red = Math.min(255, Math.max(red, 0));
                    green = Math.min(255, Math.max(green, 0));
                    blue = Math.min(255, Math.max(blue, 0));
                    result.setRGB(x, y, new Color(red, green, blue, alpha).getRGB());
                }
            }
        }
        return result;
    }
}
